//
//  IOFunction.cpp
//  lilTerm
//
//  Created by Threese on 2019/7/22.
//  Copyright © 2019 Threese. All rights reserved.
//

#include "IOFunction.h"

using namespace std;

int getLength(IPlan *p){
    int count = 0;
    
    IPlan *temp = p;
    
    while(temp){
        temp = const_cast<IPlan*>(temp->getNext());
        count++;
    }
    
    return count;
}

int getLength(ITimeLine *t){
    int count = 0;
    
    ITimeLine *temp = t;
    
    while(temp){
        temp = temp->getNext();
        count++;
    }
    
    return count;
}

int getLength(ITask *t){
    int count = 0;
    
    const ITask *temp = t;
    
    while(temp){
        temp = temp->getNext();
        count++;
    }
    
    return count;
}


int checkHead(string buff){
    string head = "06hkllxx";
    
    if(buff == head)
        return 1;
    else
        return 0;
}

IPlan *ctrlOpen(std::string fileName){
    IPlan *returnP = new CPlan();
    
    ifstream fin;
    fin.open(fileName);
    
    if(fin.is_open()){
        string buff;
        int numBuff;
        getline(fin, buff);
        if(checkHead(buff) == 1){
            
            int planSize = 0;
            fin >> planSize;
            getline(fin, buff);
            
            for(int i = 0;i < planSize;i++){
                IPlan *p = new CPlan( );
                getline(fin, buff);
                p->setName(buff);
                getline(fin, buff);
                p->setLabel(buff);
                
                getline(fin, buff);
                string rm = "";
                while(true){
                    rm += buff;
                    getline(fin, buff);
                    
                    if(buff == "$#$remarrrrrrksE")
                        break;
                    else
                        rm += "\n";
                }
                p->setRemarks(rm);
                
                int timelineSize = 0;
                fin >> timelineSize;
                getline(fin, buff);
                
                for(int j = 0;j < timelineSize;j++){
                    ITimeLine *timelinePtr;
                    timelinePtr = new CTimeLine();
                    getline(fin, buff);
                    timelinePtr->setName(buff);
                    int taskSize = 0;
                    fin >> taskSize;
                    getline(fin, buff);
                    for (int k = 0; k < taskSize; k++) {
                        ITask *taskPtr;
                        taskPtr = new CTask( );
                        getline(fin, buff);
                        taskPtr->setName(buff);
                        getline(fin, buff);
                        taskPtr->addLabel(buff);
                        getline(fin, buff);
                        rm = "";
                        while(true){
                            rm += buff;
                            getline(fin, buff);
                            
                            if(buff == "$#$remarrrrrrksE")
                                break;
                            else
                                rm += "\n";
                        }
                        taskPtr->setRemarks(rm);
                        CDate time;
                        int year, month, day, hour, minute, second;
                        fin >> year >> month >> day >> hour >> minute >> second;
                        getline(fin, buff);
                        time.setDate(year, month, day, hour, minute, second);
                        taskPtr->setStartDate(time);
                        fin >> year >> month >> day >> hour >> minute >> second;
                        getline(fin, buff);
                        time.setDate(year, month, day, hour, minute, second);
                        taskPtr->setEndDate(time);
                        fin >> numBuff;
                        getline(fin, buff);
                        taskPtr->setImportance(numBuff);
                        
                        timelinePtr->addTask(taskPtr);
                        //timelinePtr;
                    }
                    
                    p->addTimeLine(timelinePtr);
                }
                
                returnP->add(p);
            }
            fin.close();
            
            return const_cast<IPlan*>(returnP->getNext());
        }
    }
    
    return nullptr;
}

void ctrlSave(std::string fileName, IPlan *pp){
    ofstream fout;
    fout.open(fileName);
    
    if(fout.is_open()){
        fout << "06hkllxx" << endl;
        
        int planSize = getLength(pp);
        fout << planSize << endl;
        
        const IPlan *p = pp;
        for(int i = 0;i < planSize;i++){
            fout << p->getName() << endl;
            fout << p->getLabel() << endl;
            fout << p->getRemarks() << endl;
            fout << "$#$remarrrrrrksE" << endl;
            
            ITimeLine *tl = pp->getTimeLine(0);
            int timelineSize = getLength(p->getTimeLine(0));
            fout << timelineSize << endl;
            for(int j = 0;j < timelineSize;j++){
                fout << tl->getName() << endl;
                
                //debug
                int taskSize = getLength(tl->getTask());
                fout << taskSize << endl;
                const ITask *t = tl->getTask();
                for(int k = 0;k < taskSize;k++){
                    fout << t->getName() << endl;
                    fout << t->getLabel() << endl;
                    fout << t->getRemarks() << endl;
                    fout << "$#$remarrrrrrksE" << endl;
                    IDate *sD = t->getStartDate();
                    fout << sD->getYear() << " " << sD->getMonth() << " " <<
                    sD->getDay() << " " << sD->getHour() << " " << sD->getMinute() <<
                    " " << sD->getSecond() << endl;
                    IDate *eD = t->getEndDate();
                    fout << eD->getYear() << " " << eD->getMonth() << " " <<
                    eD->getDay() << " " << eD->getHour() << " " << eD->getMinute() <<
                    " " << eD->getSecond() << endl;
                    fout << t->getImportance() << endl;
                    
                    t = t->getNext();
                }
                
                tl = tl->getNext();
            }
            
            p = p->getNext();
        }
        
        fout.close();
    }
    else{
        //TODO
    }
}
